package org.anderground.app.activity;

import java.util.Stack;

import org.anderground.app.AndergroundApp;
import org.anderground.core.Logger;

/**
 * @author Eldar Abusalimov
 */
public class StateStack {

	public final State VOID_STATE;

	/**
	 * @author Eldar Abusalimov
	 */
	public static abstract class State {

		private AndergroundApp app;

		public State(AndergroundApp app) {
			this.app = app;
		}

		public boolean enterFrom(State state) {
			return true;
		}

		public boolean advanceTo(State state) {
			return true;
		}

		public void exit() {
		}

		/**
		 * @return the app
		 */
		public final AndergroundApp getApp() {
			return app;
		}

	}

	private Stack<State> stack = new Stack<State>();

	public StateStack(AndergroundApp app) {
		VOID_STATE = new VoidState(app);

		stack.push(VOID_STATE);
	}

	public boolean popState() {
		State state = stack.peek();
		Logger.d(state + " pop");
		state.exit();
		stack.pop();
		if (stack.isEmpty()) {
			stack.push(VOID_STATE);
			return false;
		}
		if (!stack.peek().enterFrom(state)) {
			return popState();
		}
		return true;
	}

	public boolean pushState(State state) {
		Logger.d(state + " push");
		stack.remove(state);
		State current = null;
		if (!stack.isEmpty()) {
			current = stack.peek();
			if (!current.advanceTo(state)) {
				stack.pop();
			}
		}
		stack.push(state);
		if (!state.enterFrom(current)) {
			popState();
			return false;
		}
		return true;
	}

}
